//----------------------------------*-C++-*----------------------------------//
/*!
 * \file   SlabtranProblem.hh
 * \author Jeremy Roberts
 * \date   04/11/2011
 * \brief  SlabtranProblem class definition.
 * \note   Copyright (C) 2011 Jeremy Roberts
 */
//---------------------------------------------------------------------------//
// $Rev:: 123                                           $:Rev of last commit
// $Author:: j.alyn.roberts@gmail.com                   $:Author of last commit
// $Date:: 2011-08-25 12:30:43 +0000 (Thu, 25 Aug 2011) $:Date of last commit
//---------------------------------------------------------------------------//

#ifndef SLABTRANPROBLEM_HH
#define SLABTRANPROBLEM_HH

#include <iostream>
#include <vector>

#include "tran/SlabtranElement.hh"
#include "tran/SlabtranInput.hh"
#include "tran/CartMesh.hh"
#include "material/Materials.hh"
#include "tran/State.hh"
#include "tran/Traits.hh"
#include "tran/SlabtranSolver.hh"
#include "tran/DD_1D_Equations.hh"
#include "tran/Definitions.hh"
#include "angle/AngularMesh.hh"
#include "source/BaseSource.hh"
#include "../utilities/SP.hh"

namespace slabtran
{

//===========================================================================//
/*!
 * \class SlabtranProblem
 * \brief A manager class for slabtran problems.
 *
 * A single instance of \ref SlabtranProblem manages a single slabtran
 * problem.  That is, for response function calculations, a manager is
 * instantiated for each incident condition.
 *
 * This class was largely inspired by Denovo's Manager class.
 *
 * Note to developer: for each new equation type, a new template instantiation
 * of SlabtranProblem must be included in \ref SlabtranProblem.cc.
 *
 * \note A likely future goal will be to use python as a front end.  Most
 *       of the c++ code should remain hidden, but this manager class
 *       could be the main interface point (or, everything it does could
 *       be done in python for even more flexibility).
 *
 * \example test/test_SlabtranProblem.cc
 *
 * Test of SlabtranProblem
 *
 */
//===========================================================================//
template <class Equations, class D>
class SlabtranProblem
{

public:

  //@{
  //! Useful typedefs for classes that use SlabtranProblem
  typedef SlabtranInput::SP_input                   SP_input;
  typedef SlabtranElement::SP_element               SP_element;
  typedef typename Base_Mesh::SP_mesh	            SP_mesh;
  typedef Materials::SP_materials                   SP_materials;
  typedef typename BaseSource<D>::SP_source         SP_source;
  typedef typename AngularMesh<D>::SP_angularmesh   SP_angularmesh;
  typedef SlabtranSolver::SP_solver                 SP_solver;
  //@}

  // constructor
  SlabtranProblem(SlabtranInput input, int elid);

  // destructor
  ~SlabtranProblem();

  // where are boundary conditions set i.e. for rf's?


protected:

  /// Problem input.
  SP_input d_input;

  /// Geometry description from input.
  SP_element d_element;

  /// Element identifier.
  int d_element_id;

  /// Mesh.
  SP_mesh d_mesh;

  /// Materials library.
  SP_materials d_materials;

  /// Angular mesh.
  SP_angularmesh d_octants;

  /// External source.
  SP_source d_source;

  /// \brief my solver
  SP_solver d_solver;

  // Problem set-up

  void build_source();

};

} // end namespace slabtran

#endif // SLABTRANPROBLEM_HH
//---------------------------------------------------------------------------//
//                 end of SlabtranProblem.hh
//---------------------------------------------------------------------------//

